package com.yonyou.cyxdms.sysAuth.service.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.exception.DALException;
import com.yonyou.cyx.function.utils.bean.BeanMapperUtil;
import com.yonyou.cyx.function.utils.common.StringUtils;
import com.yonyou.cyxdms.framework.bean.dto.user_info.LoginInfoDto;
import com.yonyou.cyxdms.sysAuth.service.dto.ConsultantWorkDTO;
import com.yonyou.cyxdms.sysAuth.service.entity.ConsultantWorkPO;
import com.yonyou.cyxdms.sysAuth.service.entity.EmpPo;
import com.yonyou.cyxdms.sysAuth.service.mapper.ConsultantWorkMapper;
import com.yonyou.cyxdms.sysAuth.service.mapper.EmployeeMapper;
import com.yonyou.cyxdms.sysAuth.service.service.ConsultantWorkService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author tanjie
 * @since 2019-08-14
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ConsultantWorkServiceImpl extends ServiceImpl<ConsultantWorkMapper, ConsultantWorkPO> implements ConsultantWorkService {
    //日志对象
    private static final Logger logger = LoggerFactory.getLogger(ConsultantWorkServiceImpl.class);
    @Autowired
    ConsultantWorkMapper consultantWorkMapper;

    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 分页查询对应数据
     *
     * @param page           分页对象
     * @param queryCondition 查询条件
     * @return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map < java.lang.String, java.lang.Object>>
     * @author tanjie
     * @since 2018/7/22 0022
     */
    @Override
    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public IPage<Map<String, Object>> selectPageBysql(Page page, Map<String, Object> queryCondition) {
        // 获取总条数
        page.setRecords(consultantWorkMapper.selectPageBySql(page, queryCondition));
        return page;
    }

    /**
     * 根据查询条件返回结果集
     *
     * @param queryCondition 查询条件
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author tanjie
     * @since 2018/7/22 0022
     */
    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> selectListBySql(Map<String, Object> queryCondition) {
        return consultantWorkMapper.selectListBySql(queryCondition);
    }

    /**
     * 根据查询条件返回结果集
     *
     * @param id 主键ID
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Object>>
     * @author tanjie
     * @since 2018/7/22 0022
     */
    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getById(Long id) {
        ConsultantWorkPO consultantworkpo = consultantWorkMapper.selectById(id);
        if (consultantworkpo != null) {
            return consultantworkpo.toMaps();
        } else {
            throw new DALException("查询失败,没有符合条件的数据");
        }
    }

    /**
     * 根据DTO 进行数据新增
     *
     * @param consultantWorkDTO 页面DTO
     * @return void
     * @author zhangxianchao
     * @since 2018/7/21 0021
     */
    @Override
    public Map<String, Object> insert(ConsultantWorkDTO consultantWorkDTO) {
        //对对象进行赋值操作
        ConsultantWorkPO consultantworkpo = consultantWorkDTO.transDtoToPo(ConsultantWorkPO.class);
        //执行插入
        consultantWorkMapper.insert(consultantworkpo);
        //返回插入的值
        return consultantWorkMapper.selectById(consultantworkpo.getConsultantWorkId()).toMaps();
    }

    /**
     * 根据DTO 及ID 进行数据更新
     *
     * @param id                主键ID
     * @param consultantWorkDTO 页面DTO
     * @return void
     * @author zhangxianchao
     * @since 2018/7/21 0021
     */
    @Override
    public Map<String, Object> update(Long id, ConsultantWorkDTO consultantWorkDTO) {
        ConsultantWorkPO consultantworkpo = consultantWorkMapper.selectById(id);
        //对对象进行赋值操作
        consultantWorkDTO.transDtoToPo(consultantworkpo);
        //执行更新
        consultantWorkMapper.updateById(consultantworkpo);
        return consultantworkpo.toMaps();
    }

    /**
     * 根据ID 进行删除数据
     *
     * @param id
     * @return void
     * @author zhangxianchao
     * @since 2018/8/25 0025
     */
    @Override
    public void deleteById(Long id) {
        int deleteCount = consultantWorkMapper.deleteById(id);
        logger.debug("删除数量：{}", deleteCount);
        if (deleteCount <= 0) {
            throw new DALException("删除失败,没有符合条件的数据");
        }
    }

    /**
     * 通过经销商CODE查询出所有当天工作的顾问与已经分配线索的权重
     *
     * @param:
     * @return: Map<顾问id, 当前权重比例>
     * @auther: tanjie
     * @since: 2019/8/14
     */
    @Override
    public Map<String, Integer> getWorkConsultantRatioByDealerCode(String dealerCode) {
        int workDay = LocalDateTime.now().getDayOfWeek().getValue();
        //当前经销商分配给顾问的总线索数
        Integer clues = consultantWorkMapper.getCluesByConsul(dealerCode, workDay);
        //当前顾问分配的线索数
        List<ConsultantWorkPO> resultConsult = consultantWorkMapper.getRatioByClues(dealerCode, workDay);

        //查询总个数算出比例
        Map<String, Integer> map = new HashMap<>();
        for (ConsultantWorkPO consultantworkpo : resultConsult) {

            map.put(consultantworkpo.getConsultantId(),
                    (int) (consultantworkpo.getCluesByDay() / (double) clues * 100));
        }
        return map;
    }

    /**
     * 修改顾问当天线索数
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/15
     */
    @Override
    public Integer updateConsultantClues(String consultId, Integer num) {
        return consultantWorkMapper.updateConsultantClues(consultId, num);
    }

    /**
     * 修改 顾问服务时间
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/15
     */
    @Override
    public Integer updateConsultWorkTime(String consultId, List<Integer> workDay) {
        if (null == workDay || workDay.size() == 0) {
            return 0;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < workDay.size(); i++) {
            if (i == workDay.size() - 1) {
                sb.append(workDay.get(i));
                break;
            }
            sb.append(workDay.get(i) + "&");
        }

        return consultantWorkMapper.updateConsultWorkTime(consultId, sb.toString());
    }

    /**
     * 修改顾问分配信息
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/28
     */
    @Override
    public Boolean updateConsult(ConsultantWorkDTO consultantWorkDTO) {


        return this.addConsultWork(consultantWorkDTO);
    }


    /**
     * 根据经销商获取 对应顾问分配 信息
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/28
     */
    @Override
    public List<Map<String, Object>> consultantWorkInfo() {
        //获取登陆信息
        LoginInfoDto beanByType = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String loginOwnerCode = beanByType.getOwnerCode();
        logger.info("根据经销商{}获取 对应顾问分配信息", loginOwnerCode);
        List<EmpPo> emp = consultantWorkMapper.queryAllotConsultant(loginOwnerCode, true, null);
        List<Map<String, Object>> consults = new ArrayList<>();
        for (EmpPo empPo : emp) {
            ConsultantWorkDTO consultant = new ConsultantWorkDTO();
            consultant.setPhone(empPo.getMobilePhone());
            consultant.setName(empPo.getEmployeeName());
            consultant.setConsultantId(empPo.getEmpId().toString());
            try {
                LambdaQueryWrapper<ConsultantWorkPO> query = new QueryWrapper<ConsultantWorkPO>().lambda();
                query.eq(ConsultantWorkPO::getConsultantId, empPo.getEmpId());
                ConsultantWorkPO result = consultantWorkMapper.selectOne(query);
                BeanMapperUtil.copyProperties(result, consultant);
                //解析线索来源
                String sourceType = consultant.getSourceType();
                if (null == sourceType || sourceType.trim() == "") {
                    consultant.setSourceType("全部");
                } else {
                    String[] split = sourceType.split("&");
                    consultant.setSourceType(this.parseKey(split));
                }
                //解析工作时间
                String[] workTimeArr = consultant.getWorkTime().split("&");
                consultant.setWorkTime(this.parseKey(workTimeArr));
            } catch (Exception e) {
                logger.debug("获取经销商的配置了分配信息的顾问错误",e);
                continue;
            }
            Map<String, Object> resultMap = BeanMapperUtil.toMap(consultant);
            Integer isAllot = consultant.getIsAllot();
            resultMap.put("isAllot", isAllot == 1 ? "是" : "否");
            consults.add(resultMap);
        }
        return consults;
    }

    /**
     * 线索来源 与服务时间映射表
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/30
     */
    public String parseKey(String[] split) {
        HashMap<String, String> oriMap = new HashMap<>();
        /*Map<String, String> map = new HashMap<String, String>() {
            {
                put("1", "周一");
                put("2", "周二");
                put("3", "周三");
                put("4", "周四");
                put("5", "周五");
                put("6", "周六");
                put("7", "周日");
            }
        };*/
        Map<String, String> map = new HashMap<>();
        map.put("1", "周一");
        map.put("2", "周二");
        map.put("3", "周三");
        map.put("4", "周四");
        map.put("5", "周五");
        map.put("6", "周六");
        map.put("7", "周日");
        // = Map.of("1", "周一", "2", "周二", "3", "周三", "4", "周四", "5", "周五", "6", "周六"
        //  , "7", "周日");
        oriMap.putAll(map);
        //TODO 后续优化使用feign获取
        oriMap.put("80", "线上");
        oriMap.put("81", "线下");
        oriMap.put("82", "汽车之家");
        oriMap.put("83", "易车网");
        oriMap.put("84", "厂家下发");
        oriMap.put("85", "微信公众号");
        oriMap.put("86", "市场活动");
        oriMap.put("87", "外拓");
        oriMap.put("88", "外展");
        oriMap.put("89", "爱卡");
        oriMap.put("90", "其他");
        oriMap.put("91", "太平洋");
        oriMap.put("92", "懂车帝");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < split.length; i++) {
            if (i == split.length - 1) {
                sb.append(oriMap.get(split[i]));
                continue;
            }
            sb.append(oriMap.get(split[i]) + "、");
        }

        return sb.toString();
    }

    /**
     * 查询当前经销商未设置分配的顾问
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/28
     */
    @Override
    public List<Map<String, String>> consultantWorkNotAllotInfo(String consultId) {
        LoginInfoDto beanByType = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String loginOwnerCode = beanByType.getOwnerCode();
        logger.info("开始获取经销商{}未设置分配的顾问", loginOwnerCode);
        List<EmpPo> empPos = consultantWorkMapper.queryAllotConsultant(loginOwnerCode, false, consultId);
        if (null == empPos || empPos.size() == 0) {
            return null;
        }
        List<Map<String, String>> resultMap = new ArrayList<>();
        for (EmpPo empPo : empPos) {
            Map<String, String> map = new HashMap<>();
            map.put("phone", empPo.getMobilePhone());
            map.put("empId", empPo.getEmpId().toString());
            map.put("name", empPo.getEmployeeName());
            resultMap.add(map);
        }
        return resultMap;
    }

    /**
     * 通过顾问ID修改顾问权重
     *
     * @param map <顾问id,顾问权重> 权重以百分展示
     * @return:
     * @auther: tanjie
     * @since: 2019/8/15
     */
    @Override
    public Integer updateConsultRatio(HashMap<String, Integer> map) {
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        int count = 0;
        for (Map.Entry<String, Integer> entry : entries) {
            count += consultantWorkMapper.updateConsultRatio(entry.getKey(), entry.getValue());
        }
        return count;
    }

    /**
     * 通过经销商CODE查询出所有当天工作的顾问与设置的权重
     *
     * @param:
     * @return: Map<顾问id, 权重比例>
     * @auther: tanjie
     * @since: 2019/8/14
     */
    @Override
    public Map<String, Integer> getWorkConsultantByDealerCode(String dealerCode) {
        //先判断时间是否过期
        ConsultantWorkPO consult = this.getById(1);
        int consultDay = consult.getCluesDayValid().getDayOfWeek().getValue();
        if (consultDay != LocalDateTime.now().getDayOfWeek().getValue()) {
            //更新过期时间与线索数
            Integer integer = consultantWorkMapper.resetClues();
            logger.info("时间已过期，更新时间刷新线索数");
        }
        //获取当天服务的顾问 并获取他们的权重比例(设置的权重比例
        int workDay = LocalDateTime.now().getDayOfWeek().getValue();
        List<ConsultantWorkPO> workConsultantRatio = consultantWorkMapper.getWorkConsultantRatio(dealerCode, workDay);

        Map<String, Integer> map = new HashMap<>();
        for (ConsultantWorkPO consultantworkpo : workConsultantRatio) {
            map.put(consultantworkpo.getConsultantId(), consultantworkpo.getConsultantRatio());
        }
        return map;

    }

    /**
     * 根据ids 进行删除
     *
     * @param ids
     * @return void
     * @author zhangxianchao
     * @since 2018/8/25 0025
     */
    @Override
    public void deleteBatchIds(String ids) {
        List<Long> longList = StringUtils.convertStrToArray(ids, ",", Long.class);
        int deleteCount = consultantWorkMapper.deleteBatchIds(longList);
        logger.debug("删除数量：{}", deleteCount);
        if (deleteCount != longList.size()) {
            throw new DALException("删除失败,没有符合条件的数据");
        }
    }

    /**
     * 根据ID删除顾问分配规则
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/29
     */
    @Override
    public Boolean delConsultWorkById(String consultId) {
        LoginInfoDto login = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String ownerCode = login.getOwnerCode();
        return consultantWorkMapper.deleteByConsultantId(ownerCode, consultId) == 1;
    }

    /**
     * 添加顾问分配信息
     *
     * @param:
     * @return:
     * @auther: tanjie
     * @since: 2019/8/30
     */
    @Override
    public Boolean addConsultWork(ConsultantWorkDTO consultantWorkDTO) {
        List<Integer> date = consultantWorkDTO.getDate();
        //解析date
        if (date != null && date.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < date.size(); i++) {
                if (i == date.size() - 1) {
                    sb.append(date.get(i));
                    continue;
                }
                sb.append(date.get(i) + "&");
            }
            consultantWorkDTO.setWorkTime(sb.toString());
        }


        //获取OwnerCode
        LoginInfoDto login = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String ownerCode = login.getOwnerCode();
        consultantWorkDTO.setOwnerCode(ownerCode);

        consultantWorkDTO.setCluesByDay(0);
        //设置可分配默认值
        Integer isAllot = consultantWorkDTO.getIsAllot();
        consultantWorkDTO.setIsAllot(isAllot == null ? 1 : isAllot);
        //设置默认分配比例
        Integer ratio = consultantWorkDTO.getConsultantRatio();
        consultantWorkDTO.setConsultantRatio(null == ratio ? 10 : ratio);
        //设置服务时间默认值
        String workTime = consultantWorkDTO.getWorkTime();
        consultantWorkDTO.setWorkTime(null == workTime || workTime.trim() == "" ? "null" : workTime);
        //设置分配时间默认值
        consultantWorkDTO.setCluesDayValid(LocalDateTime.now());
        ConsultantWorkPO consultantworkpo = BeanMapperUtil.copyProperties(consultantWorkDTO, ConsultantWorkPO.class);
        LambdaQueryWrapper<ConsultantWorkPO> query = new QueryWrapper<ConsultantWorkPO>().lambda();
        query.eq(ConsultantWorkPO::getConsultantId, consultantWorkDTO.getConsultantId());
        //判断是更新还是修改
        ConsultantWorkPO one = this.getOne(query);
        LambdaQueryWrapper<ConsultantWorkPO> updateWhere = new QueryWrapper<ConsultantWorkPO>().lambda();
        updateWhere.eq(ConsultantWorkPO::getConsultantId, consultantworkpo.getConsultantId());
        return null == one ? this.save(consultantworkpo) :
                this.update(consultantworkpo, updateWhere);

    }
}
